package com.sina.shop.manage.service.foot;

import com.sina.shop.core.exception.client.DataException;
import com.sina.shop.core.exception.server.CreateException;
import com.sina.shop.core.exception.server.ResourceExistsException;
import com.sina.shop.core.exception.server.UpdateException;
import com.sina.shop.domain.Status;
import com.sina.shop.domain.admin.Admin;
import com.sina.shop.domain.foot.Foot;
import com.sina.shop.manage.dao.admin.AdminManageDao;
import com.sina.shop.manage.dao.foot.FootManageDao;
import com.sina.shop.service.ShopDataSourceService;
import com.sina.shop.util.Assert;
import com.sina.shop.util.ResultCode;
import com.sina.shop.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static com.sina.shop.service.ServiceConstant.SHOP_TX;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * 段浩杰   2018-01-15-11:00
 */
@Service("footManageService")
public class FootManageServiceImpl extends ShopDataSourceService implements FootManageService {

    @Autowired
    @Qualifier("footManageDao")
    private FootManageDao footManageDao;

    @Autowired
    @Qualifier("adminManageDao")
    private AdminManageDao adminManageDao;

    @Override
    @Transactional(value = SHOP_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public Foot getFootById(Long id) {
        return footManageDao.get(Foot.class, id);
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.REPEATABLE_READ)
    public int deleteFoot(Long id) throws DataException, UpdateException {
        Foot foot = footManageDao.get(Foot.class, id);
        Assert.assertNotNull(foot, "Foot[id=%s] not exists", foot.getId());

        try {
            return footManageDao.deleteFoot(id);
        } catch (DataAccessException e) {
            LOG.error(" {} delete Foot error.", Foot.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.READ_COMMITTED)
    public Foot saveFoot(Foot foot) throws CreateException, ResourceExistsException, DataException {
        try {

            if (foot.getGoods() != null && foot.getGoods().getId() != null && foot.getAdmin() != null && foot.getAdmin().getId() != null) {
                Foot foot1 = footManageDao.getFootByAidAndGid(foot.getAdmin().getId(), foot.getGoods().getId());
                if (foot1 != null) {
                    foot1.setCreateTime(LocalDateTime.now());
                    foot1.setStatus(Status.USE);
                    foot1 = updateFoot(foot1);
                    return foot1;
                }
            }

            footManageDao.save(foot);
            footManageDao.flush();
            return foot;
        } catch (DataAccessException e) {
            LOG.error(" {} save Foot error.", Foot.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.REPEATABLE_READ)
    public Foot updateFoot(Foot foot) throws UpdateException, DataException {
        Foot f = footManageDao.get(Foot.class, foot.getId());
        Assert.assertNotNull(f, "Foot[id=%s] not exists", foot.getId());

        try {
            f = updateFootFiled(foot, f);
            footManageDao.flush();

            return f;
        } catch (DataAccessException e) {
            LOG.error(" {} update Foot error.", Foot.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    private Foot updateFootFiled(Foot oldFoot, Foot newFoot) throws CreateException {


        if (oldFoot.getAdmin() != null) {
            newFoot.setAdmin(oldFoot.getAdmin());
        }

        if (oldFoot.getGoods() != null) {
            newFoot.setGoods(oldFoot.getGoods());
        }

        if (!StringUtils.isEmpty(oldFoot.getStatus())) {

            newFoot.setStatus(oldFoot.getStatus());
        }
        if (oldFoot.getCreateTime() != null) {
            newFoot.setCreateTime(oldFoot.getCreateTime());
        }

        return newFoot;
    }

    @Override
    @Transactional(value = SHOP_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public List<Map<String, Object>> getFootList(Foot foot, Long[] count) {
        Admin admin = null;
        if (foot.getAdmin() != null && !StringUtils.isEmpty(foot.getAdmin().getAccount())) {
            admin = adminManageDao.getAdmin(foot.getAdmin().getAccount());
            if (admin == null) {
                admin = new Admin();
            }
        }
        foot.setAdmin(admin);

        if (count != null && count.length > 0) {
            count[0] = footManageDao.getFootCount(foot);
        }

        return footManageDao.getFootList(foot);
    }
}
